import cronParser, {fieldsToExpression} from 'cron-parser'
import cronstrue from 'cronstrue';
import  "cronstrue/locales/zh_CN.js"
import  "cronstrue/locales/en.js"


// lang: en zh_CN
export function cron2human(str:string,lang:string){
  if(str === "" || str===null || str ===undefined){
    return false;
  }
  if(lang != "zh_CN" ){
    lang = "en"
  }
  try{
    // const res =  cronParser.parseExpression(str)
    // console.log(res)
    const validRes = validateCronExpression(str)
    if(!validRes){
      return false
    }
    // 设置语言选项为中文
    const options = {
      locale: lang
    };
    return cronstrue.toString(str,
      options);
  }catch (e:any) {
    console.log(e)
    return false;
  }
}

export function human2cron(humanReadableText: string){
  if(humanReadableText === "" || humanReadableText===null || humanReadableText ===undefined){
    return false;
  }
  humanReadableText= "At 11:00 PM, Monday through Friday"
  try{
    const cronExpression = cronstrue.toString(humanReadableText);
    return cronExpression
  }catch (e:any) {
    console.log(e)
    return false
  }
}

export function nextCronScheduleList(cronExpression:string,num:number,format:number,filterOptions:object|null){

  let startDate = new Date()
  let endDate = new Date(Date.now() + 3600000 * 24 * 30 * 12 * 5)   //5年后
  if(filterOptions){
    //@ts-ignore
    if(filterOptions.start){  //毫秒时间戳
      //@ts-ignore
      startDate = new Date(filterOptions.start)
    }
    //@ts-ignore
    if(filterOptions.end){  //毫秒时间戳
      //@ts-ignore
      endDate = new Date(filterOptions.end)
    }
  }
  // 设置选项，例如指定开始时间和结束时间
  const options = {
    currentDate: startDate, // 当前时间
    endDate: endDate,
    iterator: true // 返回一个可迭代对象，而不是数组
  };
  let ret = []

  try{
    // 解析 Cron 表达式并生成迭代器
    const interval = cronParser.parseExpression(cronExpression, options);
    // 输出接下来的 5 次执行时间
    for (let i = 0; i < num; i++) {
      const nextExecution = interval.next();
      //@ts-ignore
      ret.push(formatDateTime(nextExecution.value,format))
    }
  }catch (e:any) {
    console.log(e)
    return []
  }

  return ret;
}

function formatDateTime(dateTime:Date,format:number) {
  // 将日期时间对象格式化为 '0000-00-00 00:00:00' 形式
  const year = dateTime.getFullYear();
  const month = String(dateTime.getMonth() + 1).padStart(2, '0');
  const day = String(dateTime.getDate()).padStart(2, '0');
  const hours = String(dateTime.getHours()).padStart(2, '0');
  const minutes = String(dateTime.getMinutes()).padStart(2, '0');
  const seconds = String(dateTime.getSeconds()).padStart(2, '0');

  if(format == 0){
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  }else{
    return Number(Number((dateTime.getTime()) / 1000).toFixed(0))
  }
}

export function validateCronExpression(cronExpression:string) {
  if (!cronExpression) {
    return false;
  }

  // 分割 cron 表达式
  const parts = cronExpression.trim().split(/\s+/);

  // cron 表达式必须有 6 个部分（秒 分 时 日 月 周）
  if (parts.length !== 6) {
    return false;
  }

  // 定义每个字段的有效范围
  const ranges = {
    seconds: [0, 59],
    minutes: [0, 59],
    hours: [0, 23],
    dayOfMonth: [1, 31],
    months: [1, 12],
    dayOfWeek: [0, 7]  // 0 和 7 都表示周日
  };

  // 验证每个部分的格式
  // 更新正则表达式以支持更灵活的间隔设置
  const patterns = {
    seconds: /^(\*|(?:[0-9]|[1-5][0-9])(?:(?:-(?:[0-9]|[1-5][0-9])))?(?:,(?:[0-9]|[1-5][0-9])(?:(?:-(?:[0-9]|[1-5][0-9])))?)*|(?:\*|[0-9]|[1-5][0-9])\/(?:[0-9]|[1-5][0-9]))$/,
    minutes: /^(\*|(?:[0-9]|[1-5][0-9])(?:(?:-(?:[0-9]|[1-5][0-9])))?(?:,(?:[0-9]|[1-5][0-9])(?:(?:-(?:[0-9]|[1-5][0-9])))?)*|(?:\*|[0-9]|[1-5][0-9])\/(?:[0-9]|[1-5][0-9]))$/,
    hours: /^(\*|(?:[0-9]|1[0-9]|2[0-3])(?:(?:-(?:[0-9]|1[0-9]|2[0-3])))?(?:,(?:[0-9]|1[0-9]|2[0-3])(?:(?:-(?:[0-9]|1[0-9]|2[0-3])))?)*|(?:\*|[0-9]|1[0-9]|2[0-3])\/(?:[0-9]|1[0-9]|2[0-3]))$/,
    dayOfMonth: /^(\*|\?|L|(?:[1-9]|[12][0-9]|3[01])(?:(?:-(?:[1-9]|[12][0-9]|3[01])))?(?:,(?:[1-9]|[12][0-9]|3[01])(?:(?:-(?:[1-9]|[12][0-9]|3[01])))?)*|\*\/(?:[1-9]|[12][0-9]|3[01]))$/,
    months: /^(\*|(?:[1-9]|1[012])(?:(?:-(?:[1-9]|1[012])))?(?:,(?:[1-9]|1[012])(?:(?:-(?:[1-9]|1[012])))?)*|(?:\*|[1-9]|1[012])\/(?:[1-9]|1[012]))$/,
    dayOfWeek: /^(\*|\?|[0-7](?:(?:-[0-7])?(?:,[0-7])*)|[0-7]\/[0-7])$/
  };

  try {
    // 验证每个部分
    const fields = ['seconds', 'minutes', 'hours', 'dayOfMonth', 'months', 'dayOfWeek'];
    for (let i = 0; i < fields.length; i++) {
      const field = fields[i];
      const value = parts[i];

      // 检查是否匹配对应的正则表达式
      // @ts-ignore
      if (!patterns[field].test(value)) {
        return false;
      }

      // 检查数值范围（对于具体数值）
      if (!/[\*\?]/.test(value)) {
        const numbers = value.split(',');
        for (let num of numbers) {
          if (num.includes('/')) {
            // 处理步长
            num = num.split('/')[1];
          } else if (num.includes('-')) {
            // 处理范围
            const [start, end] = num.split('-').map(Number);
            if (start > end) return false;
            // @ts-ignore
            if (start < ranges[field][0] || end > ranges[field][1]) return false;
            continue;
          }
          const n = parseInt(num);
          // @ts-ignore
          if (!isNaN(n) && (n < ranges[field][0] || n > ranges[field][1])) {
            return false;
          }
        }
      }
    }

    // 检查日期和星期不能同时为 ?
    if ((parts[3] === '?' && parts[5] === '?') ||
      (parts[3] !== '?' && parts[5] !== '?')) {
      return false;
    }

    return true;
  } catch (e) {
    console.error('Cron validation error:', e);
    return false;
  }
}
